home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / ingres04.lzh / source / decomp / openrs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1985-01-23  |  10.5 KB  |  539 lines

  1. # include    <ingres.h>
  2. # include    <aux.h>
  3. # include    <tree.h>
  4. # include    <symbol.h>
  5. # include    "globs.h"
  6. # include    <sccs.h>
  7.  
  8. SCCSID(@(#)openrs.c    8.2    1/15/85)
  9.  
  10.  
  11.  
  12.  
  13. /* Defined constants for dtmode field above */
  14. # define    DTALLOC        0    /* descriptor allocated */
  15. # define    DTREL        1    /* has been openr'd -1 */
  16. # define    DTATTS        2    /* has rel+atts but not opened */
  17. # define    DTREAD        3    /* currently open for reading */
  18. # define    DTWRITE        4    /* currently open for writing */
  19.  
  20.  
  21.  
  22. /* Allocation of descriptors */
  23.  
  24. /* Globals which count #files open and maximum # of files which can be open */
  25.  
  26.  
  27. /*
  28. ** OPENRS -- routines associated with maintaining the range table for decomp
  29. **
  30. **    openrs(root) -- fill range table info about each relation.
  31. **
  32. **    closers() -- close all variables in range table.
  33. **
  34. **    openr1(varno) -- fill range table for a particular relation.
  35. **
  36. **    closer1(varno) -- close a particular relation.
  37. **
  38. **    readopen(varno) -- open a variable for reading. returns descriptor.
  39. **
  40. **    writeopen(varno) -- open a variable for writing. returns descriptor.
  41. **
  42. **    initdesc()    -- initialize the descriptor cache.
  43. **
  44. **    reldescrip(varno) -- returns descriptor for var (has rel/atts
  45. **        but might not be open).
  46. **
  47. **    desc_get(relnum, flag) -- finds a desc_tab & alloctes it for relnum.
  48. **
  49. **    desc_lru()  -- returns least recently used desc_tab.
  50. **
  51. **    desc_top(desc_tab) -- makes desc_tab most recently used.
  52. **
  53. **    desc_last(desc_tab) -- makes desc_tab the least recently used.
  54. **
  55. **    Trace Flags:
  56. **        62
  57. */
  58. /*
  59. ** Initdesc -- initialize descriptors for range table
  60. */
  61.  
  62. initdesc(mode)
  63. int    mode;
  64. {
  65.     register struct desc_tab    *dt;
  66.     register int            i;
  67.     extern int            Equel;
  68.  
  69.  
  70.     for (dt = De.de_desc, i = 0; dt <= &De.de_desc[MAXRELN - 1]; dt++, i++)
  71.     {
  72.         dt->dtmode = DTALLOC;
  73.         dt->relnum = -2;    /* unused relnum value */
  74.         dt->dtpos = i;        /* lru order */
  75.     }
  76.  
  77.     /*
  78.     ** Determine number of available file descriptors.
  79.     **    av_files gives number of files that are def. open
  80.     **    for users.  if we will need to open a batch file,
  81.     **    get rid of that also.
  82.     */
  83.  
  84.     De.de_dfiles = av_files();
  85.     if (mode != mdRETR)
  86.         De.de_dfiles--;
  87.     De.de_dopnfiles = 0;
  88. }
  89. /*
  90. **    Openrs -- open source relations for query. Fill values
  91. **        in range table.
  92. */
  93.  
  94. openrs(root)
  95. QTREE    *root;
  96. {
  97.     register QTREE    *r;
  98.     register int    map, i;
  99.     DESC        *openr1();
  100.  
  101.     r = root;
  102.     map = r->sym.value.sym_root.lvarm | r->sym.value.sym_root.rvarm;
  103.  
  104. #    ifdef xDTR1
  105.     if (tTf(62, 0))
  106.         printf("OPENRS-root:%x,map:%o\n", r, map);
  107. #    endif
  108.  
  109.     for (i = 0; i < MAXRANGE; i++)
  110.         if (map & (01 << i))
  111.             openr1(i);
  112.  
  113. }
  114. /*
  115. **    Close all open relations.
  116. **    If any relations were created but never
  117. **    opened, destroy them. The only
  118. **    situation under which that can occur
  119. **    is when a rub-out occurs at an
  120. **    in opportune moment or when an error
  121. **    occurs in ovqp.
  122. */
  123.  
  124. closers()
  125. {
  126.     register int            i;
  127.     register struct desc_tab    *dt;
  128.     bool                dstr_flag;
  129.  
  130.  
  131.     for (dt = De.de_desc; dt <= &De.de_desc[MAXRELN - 1]; dt++)
  132.         desc_close(dt);
  133.  
  134.     /* destroy any temps */
  135.     initp();    /* init parameters vector for destroys */
  136.     dstr_flag = FALSE;
  137.     while (i = rnum_last())
  138.     {
  139.         dstr_flag |= dstr_mark(i); /* indicate that there are relations to be destroyed */
  140.     }
  141.  
  142.     if (dstr_flag)
  143.         call_dbu(mdDESTROY, TRUE);
  144.     else
  145.         resetp();
  146. }
  147. /*
  148. **    Openr1 -- open relation to get relation relation tuple
  149. **
  150. **    This will not open the relation for reading -- only
  151. **    for getting the first part of the descriptor filled
  152. */
  153.  
  154. DESC *
  155. openr1(var)
  156. int    var;
  157. {
  158.     register struct desc_tab    *dt;
  159.     register struct rang_tab    *rp;
  160.     register DESC    *d;
  161.     int                i;
  162.     struct desc_tab            *desc_get();
  163.     extern char            *rnum_convert();
  164.  
  165.     rp = &De.de_rangev[var];
  166.  
  167. #    ifdef xDTR1
  168.     if (tTf(62, 2))
  169.         printf("openr1: var %d (%s)\t", var, rnum_convert(rp->relnum));
  170. #    endif
  171.  
  172.     dt = desc_get(rp->relnum, TRUE);
  173.  
  174.     if (dt->dtmode == DTALLOC)
  175.     {
  176.         if (i = openr(&dt->desc, OR_RELTID, rnum_convert(rp->relnum)))
  177.             syserr("openr1 open %d %s", i, rnum_convert(rp->relnum));
  178.         dt->dtmode = DTREL;
  179.     }
  180.  
  181. #    ifdef xDTR1
  182.     if (tTf(62, 2))
  183.         printf("tups=%ld\n", dt->desc.reldum.reltups);
  184. #    endif
  185.  
  186.     d = &dt->desc;
  187.  
  188.     rp->rtspec = d->reldum.relspec;
  189.     rp->rtstat = d->reldum.relstat;
  190.     rp->rtwid = d->reldum.relwid;
  191.     rp->rtcnt = d->reldum.reltups;
  192.  
  193.     return (d);
  194. }
  195. /*
  196. **  CLOSER1
  197. */
  198.  
  199. closer1(var)
  200. int    var;
  201. {
  202.     register struct desc_tab    *dt;
  203.     register struct rang_tab    *rp;
  204.     register int            i;
  205.     struct desc_tab            *desc_get();
  206.     struct desc_tab            *desc_last();
  207.  
  208.     i = var;
  209.     rp = &De.de_rangev[i];
  210.  
  211. #    ifdef xDTR1
  212.     if (tTf(62, 4))
  213.         printf("closer1:var %d (%s)\n", i, rnum_convert(rp->relnum));
  214. #    endif
  215.     if (dt = desc_get(rp->relnum, FALSE))
  216.     {
  217.  
  218.         /* currently a descriptor for rel */
  219.         desc_close(dt);
  220.  
  221.         dt->relnum = -2;
  222.         desc_last(dt);
  223.  
  224.     }
  225. }
  226. /*
  227. **  READOPEN
  228. */
  229.  
  230. DESC *
  231. readopen(var)
  232. int    var;
  233. {
  234.     register struct desc_tab    *dt;
  235.     struct desc_tab            *desc_get();
  236.  
  237.     /* get descv for the relation */
  238.     dt = desc_get(De.de_rangev[var].relnum, TRUE);
  239.  
  240.     if (!(dt->dtmode == DTREAD || dt->dtmode == DTWRITE))
  241.     {
  242.         /* not open for reading or writing */
  243.         openup(dt, var, OR_READ);    /* open for reading */
  244.     }
  245.  
  246.     return (&dt->desc);
  247. }
  248. /*
  249. **  WRITEOPEN
  250. */
  251.  
  252. DESC *
  253. writeopen(var)
  254. int    var;
  255. {
  256.     register struct desc_tab    *dt;
  257.  
  258.     /* get descv for the relation */
  259.     dt = desc_get(De.de_rangev[var].relnum, TRUE);
  260.  
  261.     if (dt->dtmode != DTWRITE)
  262.     {
  263.         /* not open for writing */
  264.         openup(dt, var, OR_WRITE);    /* open for reading */
  265.     }
  266.  
  267.     return (&dt->desc);
  268. }
  269. /*
  270. **  SPECOPEN -- open for writing not associated with any variable
  271. */
  272.  
  273. DESC *
  274. specopen(relnum)
  275. int    relnum;
  276. {
  277.     register struct desc_tab    *dt;
  278.     struct desc_tab            *desc_get();
  279.  
  280.     dt = desc_get(relnum, TRUE);
  281.  
  282.     if (dt->dtmode != DTWRITE)
  283.         openup(dt, -1, OR_WRITE);
  284.  
  285.     return (&dt->desc);
  286. }
  287. /*
  288. **  SPECCLOSE
  289. */
  290.  
  291. specclose(relnum)
  292. int    relnum;
  293. {
  294.     register struct desc_tab    *dt;
  295.     struct desc_tab            *desc_get();
  296.     struct desc_tab            *desc_last();
  297.  
  298.     if (dt = desc_get(relnum, FALSE))
  299.     {
  300.         desc_close(dt);
  301.         desc_last(dt);
  302.         dt->relnum = -2;
  303.     }
  304. }
  305. /*
  306. **    Openup -- make sure that the given descriptor is open
  307. **        suitably for reading or writing.
  308. */
  309.  
  310. openup(dt1, varno, mode)
  311. struct desc_tab    *dt1;
  312. int        varno;
  313. int        mode;
  314. {
  315.     register struct desc_tab    *dt;
  316.     register int            md, openmd;
  317.     int                i;
  318.     extern char            *rnum_convert();
  319.     char                rnam_tmp[MAXNAME+3];
  320.  
  321.     /* quick check to handle typical case of rel being already open */
  322.     md = mode;
  323.     dt = dt1;
  324.     if ((md != OR_WRITE && dt->dtmode == DTREAD) || dt->dtmode == DTWRITE)
  325.         return;
  326.  
  327.     /* relation not opened correctly */
  328.     switch (dt->dtmode)
  329.     {
  330.  
  331.       case DTALLOC:
  332.         /*
  333.         ** Descriptor allocated but nothing else. If this
  334.         ** is for a variable then use openr1 to get range table
  335.         ** info. Else open directly.
  336.         */
  337.         if (varno < 0)
  338.         {
  339.             /* open unassociated with a range table variable */
  340.             openmd = md ? OR_WRITE : OR_READ;
  341.             bmove(rnum_convert(dt->relnum), dt->desc.reldum.relid, MAXNAME);
  342.             break;
  343.         }
  344.  
  345.         /* open for range table variable */
  346.         openr1(varno);
  347.  
  348.         /* now fall through to DTREL case */
  349.  
  350.       case DTREL:
  351.         /* relation relation tuple present but nothing else */
  352.         openmd = md ? OR_AWRITE : OR_AREAD;    /* open AREAD for read, AWRITE for write */
  353.         break;
  354.  
  355.       case DTATTS:
  356.         /* relation & attributes filled but relation closed */
  357.         openmd = md ? OR_REWRITE : OR_REREAD;
  358.         break;
  359.       case DTREAD:
  360.         /* relation open for reading but we need to write */
  361.         desc_close(dt);
  362.  
  363.         openmd = OR_REWRITE;
  364.         break;
  365.  
  366.       default:
  367.         syserr("openup:bad md %d", dt->dtmode);
  368.     }
  369.  
  370.     /* close a previous file if necessary */
  371.     if (De.de_dopnfiles == De.de_dfiles)
  372.         desc_victum();    /* close oldest file */
  373.  
  374.     /* now open relation */
  375.     bmove(dt->desc.reldum.relid, rnam_tmp, MAXNAME + 3);
  376.     if (i = openr(&dt->desc, openmd, rnam_tmp))
  377.         syserr("openup:openr %d,%d,%.12s,%s", i, openmd, rnam_tmp, rnum_convert(dt->relnum));
  378.     De.de_dopnfiles++;
  379.  
  380.     /* update mode of descriptor */
  381.     dt->dtmode = md ? DTWRITE : DTREAD;
  382. }
  383. /*
  384. **  DESC_GET
  385. */
  386.  
  387. struct desc_tab *
  388. desc_get(relnum, flag)
  389. int    relnum;
  390. bool    flag;
  391. {
  392.     register struct desc_tab    *dt, *ret;
  393.     struct desc_tab            *desc_lru();
  394.  
  395.     ret = NULL;
  396.  
  397.     /* search for one currently allocated */
  398.     for (dt = &De.de_desc[0]; dt <= &De.de_desc[MAXRELN-1]; dt++)
  399.     {
  400.         if (dt->relnum == relnum)
  401.         {
  402.             ret = dt;
  403. #            ifdef xDTR1
  404.             if (tTf(62, 3))
  405.                 printf("found desc for %d\n", relnum);
  406. #            endif
  407.             break;
  408.         }
  409.     }
  410.  
  411.     if (ret == NULL && flag)
  412.     {
  413.         /* get a victim and deallocate desc */
  414.         ret = desc_lru();
  415.  
  416.         /* deallocate */
  417. #        ifdef xDTR1
  418.         if (tTf(62, 5))
  419.             printf("trading %d for %d\n", ret->relnum, relnum);
  420. #        endif
  421.         desc_close(ret);
  422.  
  423.         /* allocate */
  424.         ret->relnum = relnum;
  425.         ret->dtmode = DTALLOC;
  426.     }
  427.  
  428.     if (ret != NULL)
  429.         desc_top(ret);
  430.  
  431.     return (ret);
  432. }
  433. /*
  434. **    For text space reasons only, the close relation routine varies
  435. **    between decomp and decomp70. In decomp, the relation is opened
  436. **    only for reading and never for writing thus inpcloser() can be
  437. **    called. For decomp70 closer() must be called. If there were no
  438. **    text space shortage, then closer() could always be called.
  439. **    The routine init_decomp() assigned the value to Des_closefunc.
  440. */
  441.  
  442. extern int    (*Des_closefunc)();    /* either &inpcloser or &closer */
  443.  
  444. desc_close(dt1)
  445. struct desc_tab    *dt1;
  446. {
  447.     register struct desc_tab    *dt;
  448.     register int            i;
  449.  
  450.     dt = dt1;
  451.  
  452.     if (dt->dtmode == DTREAD || dt->dtmode == DTWRITE)
  453.     {
  454.         if (i = (*Des_closefunc)(&dt->desc))
  455.             syserr("desc_close:closer %d,%.12s", i, dt->desc.reldum.relid);
  456.         De.de_dopnfiles--;
  457.         dt->dtmode = DTATTS;
  458.     }
  459. }
  460. /*
  461. ** Desc_top -- make the desc_tab entry "dtx" the most recently used.
  462. */
  463.  
  464. desc_top(dt1)
  465. struct desc_tab    *dt1;
  466. {
  467.     register struct desc_tab    *dt, *dx;
  468.     register int            oldpos;
  469.  
  470.     dt = dt1;
  471.  
  472.     if ((oldpos = dt->dtpos) != 0)
  473.     {
  474.         /* descriptor isn't currently top */
  475.         for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
  476.             if (dx->dtpos < oldpos)
  477.                 dx->dtpos++;
  478.  
  479.         /* make descriptor first */
  480.         dt->dtpos = 0;
  481.     }
  482. }
  483. /*
  484. ** Desc_last -- make the desc_tab entry "dt" the least recently used.
  485. */
  486.  
  487. struct desc_tab *
  488. desc_last(dt)
  489. register struct desc_tab    *dt;
  490. {
  491.     register int            oldpos;
  492.     register struct desc_tab    *dx;
  493.  
  494.     oldpos = dt->dtpos;
  495.     for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
  496.         if (dx->dtpos > oldpos)
  497.             dx->dtpos--;
  498.  
  499.     /* make descriptor last */
  500.     dt->dtpos = MAXRELN - 1;
  501. }
  502. /*
  503. ** Desc_lru -- return least recently used descriptor
  504. */
  505.  
  506. struct desc_tab *
  507. desc_lru()
  508. {
  509.     register struct desc_tab    *dx;
  510.  
  511.     for (dx = De.de_desc; dx <= &De.de_desc[MAXRELN-1]; dx++)
  512.     {
  513.         if (dx->dtpos == MAXRELN - 1)
  514.             return (dx);
  515.     }
  516.     syserr("desc_lru:no lru");
  517.     /*NOTREACHED*/
  518. }
  519.  
  520.  
  521. desc_victum()
  522. {
  523.     register struct desc_tab    *dt, *old;
  524.  
  525.     old = NULL;
  526.     for (dt = &De.de_desc[0]; dt <= &De.de_desc[MAXRELN-1]; dt++)
  527.     {
  528.         if (dt->dtmode == DTWRITE || dt->dtmode == DTREAD)
  529.         {
  530.             if (old == NULL || dt->dtpos > old->dtpos)
  531.                 old = dt;
  532.         }
  533.     }
  534.  
  535.     if (old == NULL)
  536.         syserr("desc_victum:no victum %d,%d", De.de_dopnfiles, De.de_dfiles);
  537.     desc_close(old);
  538. }
  539.